Implement trip notifications and read state#449
Conversation
There was a problem hiding this comment.
@buyolitsez Looks good. There are a few problems, though.
The notification needs to be on the subtrip as the reason for 'reading' a trip might be either the person it self or the time of the visit.
The notification tab is a left over from far, far away and will be removed in the near future so we do not need to worry about that anymore.
The original discussion was to allow for digests: Immediately, daily, weekly, monthly. Starting with immediately is fine for me, but with that in mind the code might need some tinkling.
To find the members to be informed we should make use of the new spatial indices for geonames, shouldn't we?
Do we want to allow members to 'read' a leg on the visitors page (/visitors) or only on the landing page?
| $this->addSql('CREATE TABLE IF NOT EXISTS member_subtrip_read (id INT AUTO_INCREMENT NOT NULL, member_id INT NOT NULL, subtrip_id INT NOT NULL, created DATETIME NOT NULL, INDEX IDX_B1EC0277597D3FE (member_id), INDEX IDX_B1EC027F2BD7DD7 (subtrip_id), UNIQUE INDEX member_subtrip_read_unique (member_id, subtrip_id), CONSTRAINT FK_B1EC0277597D3FE FOREIGN KEY (member_id) REFERENCES member (id) ON DELETE CASCADE, CONSTRAINT FK_B1EC027F2BD7DD7 FOREIGN KEY (subtrip_id) REFERENCES sub_trips (id) ON DELETE CASCADE, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); | ||
| $this->addSql('CREATE TABLE IF NOT EXISTS member_trip_notification_sent (id INT AUTO_INCREMENT NOT NULL, member_id INT NOT NULL, trip_id INT NOT NULL, created DATETIME NOT NULL, INDEX IDX_9D9311917597D3FE (member_id), INDEX IDX_9D931191A5BC2E0E (trip_id), UNIQUE INDEX member_trip_notification_sent_unique (member_id, trip_id), CONSTRAINT FK_9D9311917597D3FE FOREIGN KEY (member_id) REFERENCES member (id) ON DELETE CASCADE, CONSTRAINT FK_9D931191A5BC2E0E FOREIGN KEY (trip_id) REFERENCES trips (id) ON DELETE CASCADE, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); | ||
| $this->addSql("INSERT INTO preferences (position, codeName, codeDescription, Description, created, DefaultValue, PossibleValues, Status) SELECT 65, 'TripsNotifications', 'trips.notifications', 'How often the member wants notifications for trips in their area', NOW(), 'No', 'No;Immediately;Daily;Weekly;Monthly', 'Normal' WHERE NOT EXISTS (SELECT 1 FROM preferences WHERE codeName = 'TripsNotifications')"); | ||
| $this->addSql("UPDATE preferences SET PossibleValues = 'No;Immediately;Daily;Weekly;Monthly' WHERE codeName = 'TripsNotifications'"); |
There was a problem hiding this comment.
This would only change the database if the previous statement didn't. For new setups that will always be the case (the situation that needs cleanup can only arise during development).
| } | ||
|
|
||
| [$preferenceValue, $period] = self::FREQUENCIES[$frequency]; | ||
| $until = new DateTimeImmutable(); |
There was a problem hiding this comment.
I always thought about trip notifications as information about upcoming trips. This seems to target trips in the past.
| use DateTime; | ||
| use Doctrine\ORM\Mapping as ORM; | ||
|
|
||
| #[ORM\Table(name: 'member_trip_notification_sent')] |
There was a problem hiding this comment.
As you hide legs of a trip notifications should be sent for legs as well, shouldn't they?
| @@ -151,25 +159,87 @@ public function markSubtripAsRead(Member $member, Subtrip $subtrip): void | |||
| } | |||
|
|
|||
| public function notifyHostsAboutTrip(Trip $trip): void | |||
There was a problem hiding this comment.
The important information is that there is a traveller visiting your area. Which means we probably want to notifyHostsAboutVisitors(SubTrip $leg).
| return $sentCount; | ||
| } | ||
|
|
||
| private function acquireTripNotificationLock(Member $member, Trip $trip): ?string |
There was a problem hiding this comment.
Which part of the database is locked here? If more than the member_leg_notification_sent table this might impact the whole site.
| @@ -37,7 +37,6 @@ class Preference | |||
| public const TRIP_NOTIFICATIONS = 'TripsNotifications'; | |||
| public const TRIP_NOTIFICATIONS_NEVER = 'No'; | |||
There was a problem hiding this comment.
Should be Never.
| @@ -0,0 +1,29 @@ | |||
| <?php | |||
There was a problem hiding this comment.
I'd expect all things trips to be in the same repository.
| @@ -0,0 +1,32 @@ | |||
| <?php | |||
There was a problem hiding this comment.
This doesn't even use the database, right? So why is it a repository?
| $entityManager = $this->createMock(EntityManagerInterface::class); | ||
| $entityManager | ||
| ->expects($this->once()) | ||
| ->expects($this->exactly(2)) |
There was a problem hiding this comment.
This binds the test against implementation which isn't necessary.
| } | ||
|
|
||
| private function createSubtripRepository(array $hosts): EntityRepository | ||
| private function createSubtripRepository(array $hosts): MatchingHostsRepository |
There was a problem hiding this comment.
A MatchingHostsRepository is not a SubtripRepository.
To close #340